﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using PGMHelper;

namespace Spectrum
{
    public class UserSpectrum: SpectSet
    {
        /// <summary>
        /// 加速度
        /// </summary>
        private double PGA { set; get; }

        /// <summary>
        /// 文件路径
        /// </summary>
        private string filePath { set; get; }

        /// <summary>
        /// 正则化
        /// </summary>
        /// <returns></returns>
        public override void Regularization()
        {
            //反应谱折减
            this.SpectrumAmplitude((float)this.GetReductionFactor());
        }

        /// <summary>
        /// 折减到1PGA所采用的折减系数
        /// </summary>
        /// <returns></returns>
        public override double GetReductionFactor()
        {
            //确定折减系数
            return 9.8E2 / (this.PGA * this.PGAMultiplier);
        }

        /// <summary>
        /// 设定反应谱
        /// </summary>
        /// <param name="jumpLine"></param>
        public void SetSpectrum(int jumpLine = 0)
        {
            //读取文件
            var strList = File.ReadAllLines(filePath).ToList();
            //初始化反应谱
            var spectList = new List<SpectParam>();
            //跳过前方信息
            for (int index = jumpLine; index < strList.Count; index++)
            {
                //行信息为空时直接返回
                if (strList[index] == string.Empty) break;
                //拆分行信息
                var subStrList = WilsonHelper.SplitStr(strList[index], new string[]
                { ",", " ", "，", "\t" });
                //行信息是否匹配
                if (subStrList.Count < 2) break;
                //读取信息
                try
                {
                    spectList.Add(new SpectParam
                    {
                        Period = Convert.ToSingle(subStrList[0]),
                        Afa = Convert.ToSingle(subStrList[1])
                    });
                }
                catch
                {
                    break;
                }
            }
            if (spectList.Count == 0)
            {
                MessageBoxExtern.Error("反应谱数据为空！");
                return;
            }
            //稀疏反应谱
            this.setSpraseSpectram(spectList);
        }

        /// <summary>
        /// 稀疏反应谱曲线
        /// </summary>
        /// <param name="paramList"></param>
        /// <param name="periodLength"></param>
        /// <param name="periodDelta"></param>
        private void setSpraseSpectram(List<SpectParam> paramList)
        {
            this.Clear();
            //决定数据点数据
            int StepNumber = (int)(this.PeriodLength / this.DeltaPeriod) + 1;
            //剔除时程相同点
            var sortDict = new SortedDictionary<float, SpectParam>();
            //初始时程排序
            paramList.ForEach(param =>
            {
                if (!sortDict.ContainsKey(param.Period))
                    sortDict.Add(param.Period, param);
            });
            paramList = sortDict.Values.ToList();
            //索引符号初始化(加速时程稀疏效果)
            int searchIndex = new int();
            //添加数据
            for (int step = 0; step < StepNumber; step++)
            {
                //确定时刻
                var time = step * this.DeltaPeriod;
                //判断是否越界
                if (searchIndex + 1 >= paramList.Count)
                {
                    this.Add((float)time, this.Last().Afa);
                    continue;
                }
                //记录前一步的值
                var preAccel = paramList[searchIndex];
                var postAccel = paramList[searchIndex + 1];
                //寻找区间
                while (time > postAccel.Period)
                {
                    //越界
                    if (++searchIndex + 1 >= paramList.Count)
                        break;
                    //确定新的迭代参数
                    preAccel = postAccel;
                    postAccel = paramList[searchIndex + 1];
                }
                //不越界直接进行线性插值
                this.Add(preAccel.Interpolation(postAccel, (float)time));
            }
        }

        /// <summary>
        /// 空的构造函数
        /// </summary>
        public UserSpectrum() : base()
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        public UserSpectrum(string filePath, double pga, double periodLength, double periodDelta, double dampRatio,
            int jumpLine = 0) : base()
        {
            //设定信息
            this.PGA = pga;
            this.filePath = filePath;
            this.PeriodLength = (float)periodLength;
            this.DeltaPeriod = (float)periodDelta;
            this.DampingRatio = (float)dampRatio;
            //设定反应谱
            this.SetSpectrum(jumpLine);
        }
    }
}
